package top.scauwlt.registry.nacos.util;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import top.scauwlt.config.RpcConfig;
import top.scauwlt.enums.RpcErrorMessageEnum;
import top.scauwlt.exception.RpcException;
import top.scauwlt.registry.RegistryClear;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author wmm
 * @Date 2022/7/28 16:01
 */
@Slf4j
public class NacosUtil implements RegistryClear {

    private static final NamingService NAMING_SERVICE;

    private static final Set<String> REGISTERED_SERVICE_NAMES = ConcurrentHashMap.newKeySet();

    static {
        NAMING_SERVICE = getNamingService();
    }

    private static NamingService getNamingService() {
        try {
            return NamingFactory.createNamingService(RpcConfig.getInstance().getRegistryAddress());
        } catch (NacosException e) {
            log.error("Nacos注册中心连接异常：", e);
            throw new RpcException(RpcErrorMessageEnum.FAILED_TO_CONNECT_TO_SERVICE_REGISTRY, e.getMessage());
        }
    }

    public static void registerService(String serviceName, InetSocketAddress inetSocketAddress) {
        try {
            NAMING_SERVICE.registerInstance(serviceName, inetSocketAddress.getHostName(), inetSocketAddress.getPort());
        } catch (NacosException e) {
            log.error("注册中心注册服务失败：", e.getMessage());
            e.printStackTrace();
        }
        REGISTERED_SERVICE_NAMES.add(serviceName);
    }

    @SneakyThrows
    public static List<String> getAllInstance(String serviceName) {
        List<Instance> instances = NAMING_SERVICE.getAllInstances(serviceName);
        List<String> addresses = new ArrayList<>();
        for (Instance instance : instances) {
            addresses.add(instance.getIp() + ":" + instance.getPort());
        }
        return addresses;
    }

    @Override
    public void clearRegistry(InetSocketAddress address) {
        if (!REGISTERED_SERVICE_NAMES.isEmpty() && address != null) {
            String host = address.getHostName();
            int port = address.getPort();
            //利用迭代器迭代注销
            Iterator<String> iterator = REGISTERED_SERVICE_NAMES.iterator();
            while (iterator.hasNext()) {
                String serviceName = iterator.next();
                try {
                    //注销服务
                    NAMING_SERVICE.deregisterInstance(serviceName, host, port);
                } catch (NacosException e) {
                    log.error("注销服务{}失败", serviceName, e);
                }
            }
        }
    }

}
